package com.bitrate.dagger.server.crawler.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bitrate.dagger.server.crawler.entity.CrawlerArticle;
import com.bitrate.dagger.server.crawler.mapper.CrawlerArticleMapper;
import com.bitrate.dagger.server.crawler.ssl.TrustAllCertManager;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.management.Query;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CrawlerService {

    @Autowired
    private CrawlerArticleMapper geekArticleMapper;

    private final String BASE_URL = "https://lianglianglee.com";

    public void execute(String category) {
        QueryWrapper<CrawlerArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title", category);
        CrawlerArticle crawlerArticleDb = geekArticleMapper.selectOne(queryWrapper);
        if (crawlerArticleDb != null) {
            Long articleId = crawlerArticleDb.getId();
            //构造访问路径
            String url = BASE_URL + "/" + category;
            try {
                Document doc = Jsoup.connect(url).get();
                Elements elements = doc.select(".book-post li");
                for (Element element : elements) {
                    String title = element.text();
                    String href = element.select("a").attr("href");
                    QueryWrapper<CrawlerArticle> queryExistsWrapper = new QueryWrapper<>();
                    queryExistsWrapper.eq("title", title);
                    queryExistsWrapper.eq("parent_id", articleId);
                    if (geekArticleMapper.selectOne(queryExistsWrapper) == null) {
                        CrawlerArticle crawlerArticle = new CrawlerArticle();
                        crawlerArticle.setTitle(title);
                        crawlerArticle.setType(2);
                        crawlerArticle.setHref(href);
                        crawlerArticle.setParentId(articleId);
                        crawlerArticle.setCreateTime(LocalDateTime.now());
                        crawlerArticle.setUpdateTime(LocalDateTime.now());
                        geekArticleMapper.insert(crawlerArticle);
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }


    public void executeArticle(Long targetParentId) {
        //查询一级类目
        QueryWrapper<CrawlerArticle> queryWrapper = new QueryWrapper<>();
        List<CrawlerArticle> crawlerArticleList = geekArticleMapper.selectList(queryWrapper);
        Map<Long, String> specialMap = new HashMap<Long, String>();
        List<CrawlerArticle> specialList = crawlerArticleList.stream().filter(e -> e.getType() == 1).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(specialList)) {
            for (CrawlerArticle crawlerArticle : specialList) {
                specialMap.put(crawlerArticle.getId(), crawlerArticle.getTitle());
            }
        }
        //查看大纲
        List<CrawlerArticle> outlineList = crawlerArticleList.stream().filter(e -> e.getType() == 2).collect(Collectors.toList());
        if (targetParentId != null) {
            outlineList = outlineList.stream().filter(e -> e.getId() >= targetParentId).collect(Collectors.toList());
        }
        if (CollUtil.isNotEmpty(outlineList)) {
            for (CrawlerArticle outlineArticle : outlineList) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                Long articleId = outlineArticle.getId();
                String jumpHref = outlineArticle.getHref();
                String url = BASE_URL + jumpHref;
                try {
                    Document doc = Jsoup.connect(url).get();
                    Elements elements = doc.select(".book-post li");
                    for (Element element : elements) {
                        String articleTitle = element.text();
                        String href = element.select("a").attr("href");
                        QueryWrapper<CrawlerArticle> queryExistsWrapper = new QueryWrapper<>();
                        queryExistsWrapper.eq("title", articleTitle);
                        queryExistsWrapper.eq("parent_id", articleId);
                        if (geekArticleMapper.selectOne(queryExistsWrapper) == null) {
                            CrawlerArticle crawlerArticle = new CrawlerArticle();
                            crawlerArticle.setTitle(articleTitle);
                            crawlerArticle.setType(3);
                            crawlerArticle.setHref(href);
                            crawlerArticle.setParentId(articleId);
                            crawlerArticle.setCreateTime(LocalDateTime.now());
                            crawlerArticle.setUpdateTime(LocalDateTime.now());
                            geekArticleMapper.insert(crawlerArticle);
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
    }


    public void executeArticleDetail() {
        QueryWrapper<CrawlerArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", 3);
        queryWrapper.isNull("content");
        List<CrawlerArticle> crawlerArticleList = geekArticleMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(crawlerArticleList)) {
            crawlerArticleList.stream().forEach(e -> {
                //文章标题
                String jumpHref = e.getHref();
                //随机休眠
                try {
                    Thread.sleep(RandomUtil.randomLong(3000, 7000));
                } catch (InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
                try {
                    // 创建自定义 TrustManager
                    TrustManager[] trustManagers = new TrustManager[]{new TrustAllCertManager()};

                    // 获取默认的 SSLContext
                    SSLContext sslContext = null;
                    try {
                        sslContext = SSLContext.getInstance("SSL");
                        sslContext.init(null, trustManagers, new java.security.SecureRandom());
                    } catch (NoSuchAlgorithmException | KeyManagementException ex) {
                        ex.printStackTrace();
                    }
                    // 应用自定义的 SSLContext
                    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
                    Document doc = Jsoup.connect(BASE_URL + jumpHref).get();
                    Element element = doc.select(".book-post div").last();
                    String content = element.html();
                    e.setContent(content);
                    geekArticleMapper.updateById(e);
                } catch (IOException ex) {
                    ex.printStackTrace();
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException exec) {
                        exec.printStackTrace();
                        return;
                    }
                }
            });
        }
    }

    public static void main(String[] args) throws IOException {
        Document doc = Jsoup.connect("http://lianglianglee.com/专栏/10x程序员工作法/00 开篇词 程序员解决的问题，大多不是程序问题.md").get();
        Element element = doc.select(".book-post div").last();
        System.out.println(element.html());
    }
}
